#include "command.h"

#include <Poco/DOM/Element.h>
using Poco::XML::Element;

#include <Poco/DOM/NodeList.h>
using Poco::XML::NodeList;

#include <Poco/DOM/Node.h>
using Poco::XML::Node;

#include <sstream>
using std::ostringstream;

#include <iostream>
using std::cout;
using std::endl;

namespace Commands{

	Command::id_type Command::_newId = 0;
	
	Command::Command(SocketAddress* s, bool needs_result) :
		_remoteHost(s!=0 ? s->host().toString() : string("")),
		_remotePort(s!=0 ? s->port() : 0),
		_resultSem(0,1),
		_resultSet(!needs_result),
		_has_result(needs_result),
		_id(Command::createNewId())
	{
	}

	Command::Command(id_type id, SocketAddress* s, bool needs_result) :
		_remoteHost(s!=0 ? s->host().toString() : string("")),
		_remotePort(s!=0 ? s->port() : 0),
		_resultSem(0,1),
		_resultSet(!needs_result),
		_has_result(needs_result),
		_id(id)
	{
	}

	string Command::hostname() const
	{
		return _remoteHost;
	}

	UInt16 Command::port() const
	{
		return _remotePort;
	}
	
	string Command::result()
	{
		if (_has_result)
		{
			if (!_resultSet)
				_resultSem.wait();
			return _result;
		}
		return string("");
	}
	
	void Command::setResult(string res, SocketAddress const)
	{
		_result = res;
		_resultSet = true;
		_resultSem.set();
	}

	Document* Command::toXML(Document* doc)
	{
		//there should be a Document here!
		NodeList* chl = doc->childNodes();
		vector<Node*> children;
		for (unsigned long i = 0; i < chl->length(); ++i)
		{
			Node* child = chl->item(i);
			children.push_back(child);
		}
		chl->release();
		
		ostringstream out;
		out << this->id();

		Element* cmd = doc->createElement("command");
		cmd->setAttribute("name", this->name());
		cmd->setAttribute("id", out.str());

		for (vector<Node*>::iterator child = children.begin(); child != children.end(); ++child)
		{
			cmd->appendChild(*child);
		}
		doc->appendChild(cmd);

		return doc;
	}

	Command::id_type Command::id() const
	{
		return _id;
	}

	Command::id_type Command::createNewId()
	{
		return _newId++;
	}
}

